package jTableTest;

/*
 * SimpleTableDemo.java requires no other files.
 */

import javax.swing.AbstractCellEditor;
import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.GroupLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class SimpleTableDemo extends JPanel {
    private boolean DEBUG = true;
    private JTable table;
    private JLabel textDisplayerLable = new JLabel("f(x)", JLabel.LEFT);
    private JLabel bookNameLabel = new JLabel("Graph Theory", JLabel.RIGHT);
    private JTextField textDisplayer = new JTextField();

    public SimpleTableDemo() {
        super();
        //setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
       // GroupLayout layout = new GroupLayout(this);
        setLayout(new GridLayout(3, 1));
        //setLayout(layout);
        add(bookNameLabel);
        bookNameLabel.setHorizontalTextPosition(JLabel.RIGHT);
        add(textDisplayerLable);
        String[] columnNames = { "Terms", "Contents", "Tags", "Micellaneous" };
        Object[][] data = { { null, null, null, null } ,
                { null, null, null, null } ,
                { null, null, null, null } ,
                { null, null, null, null } };
        table = new JTable(data, columnNames);
        table.setPreferredScrollableViewportSize(new Dimension(700, 50));
        table.setFillsViewportHeight(true);
        table.getModel().addTableModelListener(new MyTableModelListener());

        if (DEBUG) {
            table.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    if (SwingUtilities.isLeftMouseButton(e)) {
                        System.out.println("left");
                    } else if (SwingUtilities.isRightMouseButton(e)) {
                        Point p = e.getPoint();
                        table.rowAtPoint(p);
                        JPopupMenu pmenu = new JPopupMenu();
                        pmenu.add(new JMenuItem("Zoom Out"));
                        pmenu.add(new JMenuItem("Zoom In"));
                        pmenu.show(e.getComponent(), e.getX(), e.getY());
                    }
                }
            });
        }

        // Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        // Add the scroll pane to this panel.
        add(scrollPane);
        
        
    }
    
    public int getTableWidth() {
        return table.getWidth();
    }
    
    public void initView(int frameWidth) {
        int tableWidth = table.getWidth();
        TableColumn column = null;
        for (int i = 0; i < 4; i++) {
            column = table.getColumnModel().getColumn(i);
            switch (i) {
            case 0:
                column.setPreferredWidth((int) (tableWidth * BookNoteInterfaceInfo.MAX_TERMS_COLUMN_WITH_RATIO));
                break;
            case 1:
                column.setPreferredWidth((int) (tableWidth * BookNoteInterfaceInfo.MAX_CONTENTS_COLUMN_WIDTH_RATIO));
                break;
            case 2:
                column.setPreferredWidth((int) (tableWidth * BookNoteInterfaceInfo.MAX_TAGS_COLUMN_WIDTH_RATIO));
                break;
            case 3:
                column.setPreferredWidth((int) (tableWidth * BookNoteInterfaceInfo.MAX_MISC_COLUMN_WIDTH_RATIO));
                break;
            }
        }
        
    }

    
    /**
     * Create the GUI and show it. For thread safety, this method should be
     * invoked from the event-dispatching thread.
     */
    private static void createAndShowGUI() {
        // Create and set up the window.
        JFrame frame = new JFrame("SimpleTableDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create and set up the content pane.
        SimpleTableDemo newContentPane = new SimpleTableDemo();
        newContentPane.setOpaque(true); // content panes must be opaque
        frame.setContentPane(newContentPane);
        // Display the window.
        frame.pack();
        frame.setVisible(true);
        newContentPane.initView(frame.getWidth());
        
    }

    public static void main(String[] args) {
        // Schedule a job for the event-dispatching thread:
        // creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    public class MyTableModelListener implements TableModelListener {

        @Override
        public void tableChanged(TableModelEvent e) {
            int row = e.getFirstRow();
            int column = e.getColumn();
            int tableWidth = table.getWidth();
            int rowHeight = table.getRowHeight();
            int maxRowWitdh = (int) (tableWidth * BookNoteInterfaceInfo.MAX_CONTENTS_COLUMN_WIDTH_RATIO);
            FontMetrics fm = getFontMetrics(getFont());
            TableModel model = (TableModel) e.getSource();
            TableColumn col = table.getColumnModel().getColumn(column);
            String data = model.getValueAt(row, column).toString();
            if (data.length() == 0) {
               // table.setRowHeight(rowHeight);
                return;
            }
            MyTableCellEditor cellEditor = new MyTableCellEditor(row, column);
            cellEditor.setKeyListener();            
            col.setCellEditor(cellEditor);
            col.setCellRenderer(new TextAreaRenderer());
            int numLines = 0;
            
            String[] lines = StringProcessor.splitLines(data);
            for (String line : lines) {
                int stringWidth = fm.stringWidth(line);
                numLines += stringWidth / maxRowWitdh;
                if (stringWidth % maxRowWitdh != 0) {
                    numLines++;
                }
            }
            
            if (table.getRowHeight(row) < numLines * rowHeight) {
                table.setRowHeight(row, numLines * rowHeight);                
            }
//            col.setPreferredWidth(maxRowWitdh);
//            
        }

    }

    public class TextAreaRenderer extends JTextArea implements
            TableCellRenderer {

        /**
         * 
         */
        private static final long serialVersionUID = -2973944694520008085L;

        public TextAreaRenderer() {
            setLineWrap(true);
            setWrapStyleWord(true);
        }

        public Component getTableCellRendererComponent(JTable jTable,
                Object obj, boolean isSelected, boolean hasFocus, int row,
                int column) {
            setText((String) obj);
            return this;
        }
    }
    
    class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor {

        /**
         * 
         */
        private int row;
        private int column;
        
        public MyTableCellEditor () {
            
        }
        public MyTableCellEditor(int row, int column) {
            this.row = row;
            this.column = column;
        }
        private static final long serialVersionUID = 1L;
        JComponent component = new JTextArea();

        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
            int rowIndex, int vColIndex) {

          ((JTextArea) component).setText((String) value);
          return component;
        }
        
        public void setKeyListener() {
           component.addKeyListener(new KeyListener() {
            
            @Override
            public void keyTyped(KeyEvent e) {
                return;
            }
            
            @Override
            public void keyReleased(KeyEvent e) {
                return;
            }
            
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    int tableWidth = table.getWidth();
                    int rowHeight = table.getRowHeight();
                    int currentRowHeight = table.getRowHeight(row);
                    String text = ((JTextArea) component).getText();
                    String[] lines = StringProcessor.splitLines(text);
                    int maxRowWitdh = (int) (tableWidth * BookNoteInterfaceInfo.MAX_CONTENTS_COLUMN_WIDTH_RATIO);
                    int numLines = 0;
                    FontMetrics fm = getFontMetrics(getFont());
                    for (String line : lines) {
                        int stringWidth = fm.stringWidth(line);
                        numLines += stringWidth / maxRowWitdh;
                        if (stringWidth % maxRowWitdh != 0) {
                            numLines++;
                        }
                    }
                    numLines++;
                    if (numLines * rowHeight > currentRowHeight) {
                        table.setRowHeight(row, numLines * rowHeight);
                    }
                }
            }
        });
        }
        public Object getCellEditorValue() {
          return ((JTextArea) component).getText();
        }
      }
}